<?php
namespace App\Blocks;

use App\Libs\Jiguang\JMessage;
use App\Models\CrowdArticle;
use App\Models\Crowd;
use App\Models\CrowdClassify;
use App\Models\CrowdCollect;
use App\Models\CrowdFlowingWather;
use App\Models\CrowdJoinOrder;
use App\Models\CrowdMember;
use App\Models\UserMoneyLog;
use App\Models\Users;
use DB;
use zgldh\QiniuStorage\QiniuStorage;

class CrowdBlock {

    private function getCrowdListSql($search = []){
        $crowdModel         = new Crowd();
        $crowdClassifyModel = new CrowdClassify();
        $userModel          = new Users();

        $sql = DB::table($crowdModel->getTable() . ' as c')
            ->select(
                'c.id',
                'c.uid',
                'c.name',
                'c.jg_im_gid',
                'c.introduce',
                'c.headimgurl',
                'c.classify_id',
                'c.tag_ids',
                'c.grade',
                'c.member',
                'c.goods',
                'c.is_free',
                'c.is_private',
                DB::raw('round(charge / 100, 2) as charge'),
                'c.created_at',
                'cc.name as classify_name',
                'u.nick_name'
            )->leftJoin($crowdClassifyModel->getTable() . ' as cc','cc.id', '=', 'c.classify_id')
            ->leftJoin($userModel->getTable() . ' as u', 'u.id', '=', 'c.uid');

        if(isset($search['p_cid'])&&!isset($search['s_cid'])){
            $obj_cids = CrowdClassify::where('pid', $search['p_cid'])->get();

            $arr_cids = [];
            foreach ($obj_cids as $cid){
                $arr_cids[] = $cid->id;
            }

            $sql->whereIn('c.classify_id', $arr_cids);
        }elseif(isset($search['s_cid'])){
            $sql->where('c.classify_id', $search['s_cid']);
        }

        if(isset($search['search'])){
            $sql->where('c.name', 'like', "%".$search['search']."%");
        }else{
            $sql->where('c.is_private', 0);
        }
        if(isset($search['is_free'])){
            $sql->where('c.is_free', $search['is_free']);
        }

        if(isset($search['user_id'])){
            $sql->where('c.uid',$search['user_id']);
        }

        $sql->whereNull('c.deleted_at');
        return $sql;
    }

    //获取群列表
    public function getCrowdList($search = [], $page = 1, $pageSize = 20, $uid){
        $sql = $this->getCrowdListSql($search);

        $list = $sql->orderBy('c.created_at', 'desc')
            ->take($pageSize)->skip(($page - 1)*$pageSize)
            ->get();

        if (count($list)<=0){
            return [];
        }
        foreach ($list as $lists){
            $crowdIds[] = $lists->id;
        }

        $crowdMemberModel = new CrowdMember();
        $member = DB::table($crowdMemberModel->getTable())->select('crowd_id')
            ->whereIn('crowd_id',$crowdIds)
            ->where('user_id',$uid)
            ->where('deleted_at',null)
            ->get();
        $isIds = [];
        foreach ($member as $id){
            $isIds[] = $id->crowd_id;
        }
        foreach ($list as $value){
            if (count($isIds)<0){
                $value->isJoin = 0;
            }else{
                if (in_array($value->id,$isIds)){
                    $value->isJoin = 1;
                }else{
                    $value->isJoin = 0;
                }
            }

        }
        return $list;

    }

    //获取群分页数据
    public function getCrowdListPagination($search = [], $page = 1, $pageSize = 20){
        $sql = $this->getCrowdListSql($search);
        return [
            'total' => $sql->count(),
            'pageSize' => $pageSize,
            'current' => $page
        ];
    }

    //获取用户的群列表
    //收藏或者加入的群
    public function getUserCrowdList($uid, $search = [], $page = 0, $pageSize = 20){
        $crowdModel         = new Crowd();
        $crowdClassifyModel = new CrowdClassify();
        $userModel          = new Users();
        $crowdMemberModel   = new CrowdMember();
        $crowdCollectModel  = new CrowdCollect();

        $sql = DB::table($crowdMemberModel->getTable() . ' as cm');
        if(isset($search['type']) && $search['type'] == 2){
            $sql = DB::table($crowdCollectModel->getTable() . ' as cm');
        }

        $sql->select(
            'c.id',
            'c.uid',
            'c.name',
            'c.introduce',
            'c.headimgurl',
            'c.classify_id',
            'c.tag_ids',
            'c.grade',
            'c.member',
            'c.goods',
            'c.jg_im_gid',
            'c.is_free',
            'c.is_private',
            DB::raw('round(charge / 100, 2) as charge'),
            'cc.name as classify_name',
            'u.nick_name'
        )->leftJoin($crowdModel->getTable() . ' as c', function ($join) use ($uid){
            $join->on('cm.crowd_id', '=', 'c.id')
                ->on('cm.user_id', '=', DB::raw($uid));
        })->leftJoin($crowdClassifyModel->getTable() . ' as cc','cc.id', '=', 'c.classify_id')
            ->leftJoin($userModel->getTable() . ' as u', 'u.id', '=', 'c.uid');



        if(isset($search['search'])){
            $sql->where('c.name', 'like', "%".$search['search']."%");
        }
        if(isset($search['is_free'])){
            $sql->where('c.is_free', $search['search']);
        }

        $list = $sql->whereNull('cm.deleted_at')
            ->where('cm.user_id', $uid)
            ->orderBy('cm.updated_at')
            ->take($pageSize)->skip(($page - 1)*$pageSize)
            ->get();

        return $list;
    }

    //获取群信息
    public function getCrowdInfo($id){
        $crowdModel         = new Crowd();
        $crowdClassifyModel = new CrowdClassify();
        $userModel          = new Users();
        $crowdMemberModel   = new CrowdMember();
        $articleModel       = new CrowdArticle();
        $crowd = DB::table($crowdModel->getTable())->where('id',$id)->first();
        if (!$crowd){
            return [];
        }

        $userId = DB::table($crowdMemberModel->getTable())
            ->where('crowd_id',$id)->whereNull('deleted_at')->pluck('user_id');
        $userCount = $userId->count();
        $userId = json_decode(json_encode($userId),true);
        $userIds = array_slice($userId,0,3);
        $userData = DB::table($userModel->getTable())
            ->select('id','headimgurl','nick_name','signature','jg_im_username')
            ->whereIn('id',$userIds)->get();

        $articleCount = DB::table($articleModel->getTable())->where('crowd_id',$id)->count();

        $headImgUrl = [];
        $crowdUserName = '';
        foreach ($userData as $userDatum) {
            $headImgUrl[] = $userDatum->headimgurl;
            $crowdUserName = $userDatum->nick_name;
        }
        $crowdUser['headimgurl'] = $headImgUrl;
        $crowdUser['nick_name'] = $crowdUserName;

        $crowdData =  DB::table($crowdModel->getTable() . ' as c')
            ->select(
                'c.id',
                'c.uid',
                'c.name',
                'c.detailed',
                'c.headimgurl',
                'c.classify_id',
                'c.tag_ids',
                'c.grade',
                'c.jg_im_gid',
                'c.member',
                'c.goods',
                'c.is_free',
                'c.is_private',
                DB::raw('round(charge / 100, 2) as charge'),
                'c.created_at',
                'cc.name as classify_name',
                'u.jg_im_username'
            )->leftJoin($crowdClassifyModel->getTable() . ' as cc','cc.id', '=', 'c.classify_id')
            ->leftJoin($userModel->getTable() . ' as u', 'u.id', '=', 'c.uid')
            ->whereNull('c.deleted_at')
            ->where('c.id', $id)
            ->first();

        $crowdData->charge = 0.01;
        $crowdData->count =$userCount;
        $crowdData->articleCount = $articleCount;
        $crowdData->userData = $crowdUser;
        $crowdData->userList = $userData;
        $crowdData->detailed = htmlspecialchars_decode($crowdData->detailed);

        return $crowdData;

    }

    //获取群信息
    public function getCrowdInfoByJgId($id){
        $crowdModel         = new Crowd();
        $crowdClassifyModel = new CrowdClassify();
        $userModel          = new Users();

        return DB::table($crowdModel->getTable() . ' as c')
            ->select(
                'c.id',
                'c.uid',
                'c.name',
                'c.introduce',
                'c.headimgurl',
                'c.classify_id',
                'c.tag_ids',
                'c.grade',
                'c.jg_im_gid',
                'c.member',
                'c.goods',
                'c.is_free',
                'c.is_private',
                DB::raw('round(charge / 100, 2) as charge'),
                'c.created_at',
                'cc.name as classify_name'
            )->leftJoin($crowdClassifyModel->getTable() . ' as cc','cc.id', '=', 'c.classify_id')
            ->leftJoin($userModel->getTable() . ' as u', 'u.id', '=', 'c.uid')
            ->whereNull('c.deleted_at')
            ->where('c.jg_im_gid', $id)
            ->first();
    }

    //收藏群
    public function collectCrowd($uid, $crowdId){
        $collectModel = new CrowdCollect();
        return DB::table($collectModel->getTable())
            ->insert(['crowd_id' => $crowdId, 'user_id' => $uid]);
    }

    public function removeMember($memberId, $crowdId, $adminId){
        $crowdModel     = new Crowd();
        $crowd = DB::table($crowdModel->getTable())
            ->where('id', $crowdId)
            ->where('uid', $adminId)
            ->whereNull('deleted_at')
            ->first();

        if(!$crowd){
            return false;
        }
        if (is_array($memberId)){
            return $this->outCrowds($memberId, $crowdId);
        }
        return $this->outCrowd($memberId, $crowdId);
    }

    public function outCrowd($memberId, $crowdId){
        $crowdModel     = new Crowd();
        $memberModel    = new CrowdMember();
        $userModel      = new Users();

        $crowd = DB::table($crowdModel->getTable())
            ->where('id', $crowdId)
            ->whereNull('deleted_at')
            ->first();

        if(!$crowd){
            return false;
        }

        //群主不能退自己的群
        if($crowd->uid == $memberId){
            return false;
        }
        $user = DB::table($userModel->getTable())->where('id', $memberId)->first();

        if(!$user){
            return false;
        }

        try{
            DB::beginTransaction();

            if(
                DB::table($memberModel->getTable())
                    ->where('crowd_id', $crowdId)
                    ->where('user_id', $memberId)
                    ->update([
                        'deleted_at' => date('Y-m-d H:i:s', time())
                    ])
                === false){
                return false;
            }

            if(DB::table($crowdModel->getTable())->where('id', $crowdId)->decrement('member') === false){
                DB::rollBack();
                return false;
            }

            $jMessage = new JMessage();
            if(!$jMessage->outGroupMember($crowd->jg_im_gid, [$user->jg_im_username])){
                DB::rollBack();
                return false;
            }

            DB::commit();
            return true;
        }catch (\Exception $exception){
            DB::rollBack();
            \Log::error($exception);
            return false;
        }
    }

    public function outCrowds($memberId, $crowdId){
        $crowdModel     = new Crowd();
        $memberModel    = new CrowdMember();
        $userModel      = new Users();

        $crowd = DB::table($crowdModel->getTable())
            ->where('id', $crowdId)
            ->whereNull('deleted_at')
            ->first();
        if(!$crowd){
            return false;
        }

        foreach ($memberId as $k=>$v){
            $user = DB::table($userModel->getTable())->where('jg_im_username', $v)->first();
            if($user){
                $memberIds[] = $user->id;
            }
        }

        //群主不能退自己的群
        if(in_array($crowd->uid ,$memberIds)){
            return false;
        }

        try{
            DB::beginTransaction();
            $jMessage = new JMessage();
            if(!$jMessage->outGroupMember($crowd->jg_im_gid, $memberId)){
                DB::rollBack();
                return false;
            }
            foreach ($memberIds as $v){
                if(DB::table($memberModel->getTable())
                        ->where('crowd_id', $crowdId)
                        ->where('user_id', $v)
                        ->update([
                            'deleted_at' => date('Y-m-d H:i:s', time())
                        ])
                    == false){
                    return false;
                }

                if(DB::table($crowdModel->getTable())->where('id', $crowdId)->decrement('member') === false){
                    DB::rollBack();
                    return false;
                }

            }

            DB::commit();
            return true;
        }catch (\Exception $exception){
            DB::rollBack();
            \Log::error($exception);
            return false;
        }
    }

    //加入群
    public function joinCrowd($uid, $crowdId){
        $joinModel      = new CrowdJoinOrder();
        $crowdModel     = new Crowd();
        $memberModel    = new CrowdMember();

        $crowd = DB::table($crowdModel->getTable())
            ->select(
                'id',
                'charge',
                'is_free',
                'jg_im_gid'
            )
            ->where('id', $crowdId)
            ->whereNull('deleted_at')
            ->first();

        if(!$crowd){
            return false;
        }

        $joinData = [
            'crowd_id' => $crowdId,
            'user_id' => $uid,
            'charge' => $crowd->charge
        ];

        \Log::debug(json_encode($crowd));

        try{
            DB::beginTransaction();
            //如果是免费
            if($crowd->is_free){
                $joinData['charge'] = 0;
                $joinData['is_pay'] = 1;
                $joinData['pay_time'] = date('Y-m-d H:i:s', time());

                if(
                    DB::table($memberModel->getTable())->insert([
                        'crowd_id' => $crowdId,
                        'user_id' => $uid
                    ]) === false
                ){
                    DB::rollBack();
                    return false;
                }

                if(DB::table($crowdModel->getTable())->where('id', $crowdId)->increment('member') === false){
                    DB::rollBack();
                    return false;
                }

                $user = Users::where('id', $uid)->first();
                if(!$user){
                    DB::rollBack();
                    return false;
                }

                $jMessage = new JMessage();
                $jMessage->addGroupMember($crowd->jg_im_gid, [$user->jg_im_username]);
            }

            $joinOrderId = DB::table($joinModel->getTable())->insertGetId($joinData);
            if($joinOrderId === false){
                DB::rollBack();
                return false;
            }

            DB::commit();
            return $joinOrderId;

        }catch (\Exception $exception){
            DB::rollBack();
            \Log::debug($exception);
            return false;
        }
    }

    public function joinCrowdToPay($orderId){
        $joinModel      = new CrowdJoinOrder();
        $crowdModel     = new Crowd();
        $memberModel    = new CrowdMember();
        $userModel      = new Users();
        $userMoneyModel = new UserMoneyLog();

        $order = DB::table($joinModel->getTable() . ' as j')
            ->select(
                'j.id',
                'j.crowd_id',
                'j.user_id',
                'j.charge',
                'c.jg_im_gid',
                'u.jg_im_username',
                'c.uid'
            )
            ->leftJoin($crowdModel->getTable() . ' as c', 'c.id', '=', 'j.crowd_id')
            ->leftJoin($userModel->getTable() . ' as u', 'u.id', '=', 'j.user_id')
            ->where('j.id', $orderId)
            ->where('j.is_pay', 0)
            ->whereNull('j.pay_time')
            ->whereNotNull('u.id')
            ->first();

        if(!$order){
            return false;
        }

        try {
            DB::beginTransaction();

            if (
                !DB::table($memberModel->getTable())->insert([
                    'crowd_id' => $order->crowd_id,
                    'user_id' => $order->user_id
                ])
            ) {
                DB::rollBack();
                return false;
            }

            if (!DB::table($crowdModel->getTable())->where('id', $order->crowd_id)->increment('member')) {
                DB::rollBack();
                return false;
            }

            if(!DB::table($joinModel->getTable())->where('id', $order->id)->update([
                'is_pay' => 1,
                'pay_time' => date('Y-m-d H:i:s', time())
            ]) ){
                DB::rollBack();
                return false;
            }

            if(
                !DB::table($userModel->getTable())->where('id',$order->uid)->increment('balance',$order->charge)
            ){
                DB::rollBack();
                return false;
            }

            $crowdName = DB::table($crowdModel->getTable())->where('id',$order->crowd_id)->value('name');
            $userName = DB::table($userModel->getTable())->where('id',$order->user_id)->value('nick_name');

            if(
                !DB::table($userMoneyModel->getTable())->insert([
                'u_id' => $order->uid,
                'type' => 1,
                'order_id' => $orderId,
                'money' => $order->charge,
                'remake' => $userName."加入{$crowdName}群"
            ])
            ){
                DB::rollBack();
                return false;
            }



            $jMessage = new JMessage();
            $jMessage->addGroupMember($order->jg_im_gid, [$order->jg_im_username]);

            DB::commit();
            return true;

        }catch (\Exception $exception){
            DB::rollBack();
            \Log::error($exception);
            return false;
        }
    }

    //获取群成员列表
    public function getCrowdMember($crowdId, $page=1, $pageSize=20){
        $crowdMemberModel = new CrowdMember();
        $userModel = new Users();

        $member = DB::table($crowdMemberModel->getTable() . ' as cm')
            ->select(
                'u.id',
                'u.nick_name',
                'u.mobile',
                'u.headimgurl'
            )
            ->leftJoin($userModel->getTable() . ' as u', 'cm.user_id', '=', 'u.id')
            ->where('cm.crowd_id', $crowdId)
            ->whereNull('cm.deleted_at')
            ->orderBy('cm.updated_at', 'desc')
            ->skip(($page - 1) * $pageSize)->take($pageSize)
            ->get();

        return $member;
    }

    //获取群流水
    public function getCrowdFlowingWather($crowdId, $uid, $page=1, $pageSize=20){
        $crowdFlowdingWatherModel = new CrowdFlowingWather();
        $crowdModel = new Crowd();
        $sql = DB::table($crowdFlowdingWatherModel->getTable() . ' as cfw')
            ->select(
                'cfw.id',
                'cfw.crowd_id',
                'cfw.type',
                'cfw.money',
                'cfw.remark',
                'cfw.created_at',
                'c.name'
            )
            ->leftJoin($crowdModel->getTable() . ' as c', 'cfw.crowd_id', '=', 'c.id')
            ->where('uid', $uid)
            ->whereNull('deleted_at');
        if($crowdId){
            $sql->where('cfw.crowd_id', $crowdId);
        }
        $log = $sql->orderBy('created_at', 'desc')
            ->skip(($page - 1) * $pageSize)->take($pageSize)
            ->get();

        return $log;
    }

    public function createCrowd($data){
        $crowdModel = new Crowd();
        $userModel = new Users();
        $crowdMemberModel = new CrowdMember();
        try{
            $crowdUser = DB::table($userModel->getTable())->where('id', $data['uid'])->first();
            if(!$crowdUser){
                return false;
            }
            $jMessage = new JMessage();
            $gid = $jMessage->addGroup($crowdUser->jg_im_username, $data['name'], $data['introduce'], [], $data['headimgurl']);

            $data['jg_im_gid'] = $gid;

            if(!empty($data['headimgurl'])) {
                $disk = QiniuStorage::disk('qiniu');
                $disk->put('headimgurl/' . $gid, file_get_contents($data['headimgurl']));
            }

            $crowdId = DB::table($crowdModel->getTable())->insertGetId($data);
            if(!$crowdId){
                DB::rollBack();
                return false;
            }

            $memberData = array(
                'crowd_id' => $crowdId,
                'user_id' => $data['uid']
            );
            $member = DB::table($crowdMemberModel->getTable())->insert($memberData);
            if (!$member){
                DB::rollBack();
                return false;
            }
            DB::commit();
            return true;
        }catch (\Exception $exception){
            DB::rollBack();
            \Log::error($exception);
            return false;
        }
    }

    //删除群
    public function del_crowd($id){
        $crowd = new Crowd();
        $res = DB::table($crowd->getTable())->where('id',$id)->update(['deleted_at'=>date('Y-m-d H:i:s',time())]);
        return $res;
    }

    public function getCrowdMemberInfo($crowdId, $memberId){
        $crowdModel         = new Crowd();
        $crowdMemberModel   = new CrowdMember();
        $userModel          = new Users();

        $data = DB::table($crowdMemberModel->getTable() . ' as cm')
            ->select(
                'c.*',
                'u.id as user_id',
                'u.jg_im_username'
            )
            ->leftJoin($crowdModel->getTable() . ' as c', 'c.id', '=', 'cm.crowd_id')
            ->leftJoin($userModel->getTable() . ' as u', 'u.id', '=', 'cm.user_id')
            ->where('cm.crowd_id', $crowdId)
            ->where('cm.user_id', $memberId)
            ->first();

        return $data;
    }
}
